<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
            "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>



<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<META name="GENERATOR" content="hevea 1.08">
<LINK rel="stylesheet" type="text/css" href="tutorial.css">
<TITLE>
Programming Basic Behaviours
</TITLE>
</HEAD>
<BODY >
<A HREF="tutorial101.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="tutorial098.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="tutorial103.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2 CLASS="section"><A NAME="htoc204">14.4</A>&nbsp;&nbsp;Programming Basic Behaviours</H2><UL>
<LI><A HREF="tutorial102.html#toc104">Consistency Check</A>
<LI><A HREF="tutorial102.html#toc105">Forward Checking</A>
</UL>


As an example, we will look at creating constraint versions of the
following predicate.
It defines a relationship between containers of type 1, 2 or 3,
and their capacity:

	<TABLE CELLPADDING=10>
<TR><TD BGCOLOR="#CCCCFF">
	<BLOCKQUOTE CLASS="quote"><PRE>
capacity(1, N) :- N&gt;=0.0, N=&lt;350.0.
capacity(2, N) :- N&gt;=0.0, N=&lt;180.0.
capacity(3, N) :- N&gt;=0.0, N=&lt;50.0.
</PRE></BLOCKQUOTE></TD>
</TR></TABLE>
This definition gives the intended declarative meaning,
but does not behave as a constraint:
<TT>capacity(3, C)</TT> will raise an error, and
<TT>capacity(Type, 30.5)</TT> will generate several solutions nondeterministically.
Only calls like <TT>capacity(3, 27.1)</TT> will act correctly as a test.<BR>
<BR>
<A NAME="toc104"></A>
<H3 CLASS="subsection"><A NAME="htoc205">14.4.1</A>&nbsp;&nbsp;Consistency Check</H3>
<A NAME="@default370"></A>
To program the passive consistency check behaviour, we need to wait until
both arguments of the predicate are instantiated.
This can be achieved by adding an ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> <B>delay clause</B>:

	<TABLE CELLPADDING=10>
<TR><TD BGCOLOR="#CCCCFF">
	<BLOCKQUOTE CLASS="quote"><PRE>
delay capacity(T,N) if var(T);var(N).
capacity(1, N) :- N&gt;=0.0, N=&lt;350.0.
capacity(2, N) :- N&gt;=0.0, N=&lt;180.0.
capacity(3, N) :- N&gt;=0.0, N=&lt;50.0.
</PRE></BLOCKQUOTE></TD>
</TR></TABLE>
The delay clause specifies that any call to capacity/2 will delay as long
as one of the arguments is a variable. When the variables become instantiated
later, execution will be resumed automatically, and 
the instantiations will be checked for satisfying the constraint.<BR>
<BR>
<A NAME="toc105"></A>
<H3 CLASS="subsection"><A NAME="htoc206">14.4.2</A>&nbsp;&nbsp;Forward Checking</H3>
<A NAME="@default371"></A>
For Forward Checking, we will assume that we have interval domain variables,
as provided by the <B>ic</B> library (without domain variables, there would
not be much interesting propagation to be done).<BR>
<BR>
Here is one implementation of a forward checking version:

	<TABLE CELLPADDING=10>
<TR><TD BGCOLOR="#CCCCFF">
	<BLOCKQUOTE CLASS="quote"><PRE>
:- lib(ic).
delay capacity(T, N) if var(T), var(N).
capacity(T, N) :- nonvar(N), !,
        N &gt;= 0,
        ( N =&lt; 50.0 -&gt; T :: [1,2,3]
        ; N =&lt; 180.0 -&gt; T :: [1,2]
        ; N =&lt; 350.0 -&gt; T = 1
        ; fail
        ).
capacity(1, N) :- N$&gt;=0.0, N$=&lt;350.0.
capacity(2, N) :- N$&gt;=0.0, N$=&lt;180.0.
capacity(3, N) :- N$&gt;=0.0, N$=&lt;50.0.
</PRE></BLOCKQUOTE></TD>
</TR></TABLE>
Note that the delay clause now only lets goals delay when both
arguments are variables. As soon as one is instantiated, the
goal wakes up and, depending on which is the instantiated argument,
either the first, or one of the last three clauses is executed.
Some examples of the behaviour:
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
?- capacity(T, C).
There is 1 delayed goal.
Yes (0.00s cpu)

?- capacity(3, C).
C = C{0.0 .. 50.0}
Yes (0.00s cpu)

?- capacity(T, C), C = 100.
T = T{[1, 2]}
C = 100
Yes (0.00s cpu)
</PRE></BLOCKQUOTE>
A disadvantage of the above implementation is that when the predicate wakes
up, it can be either because T was instantiated, or because C was
instantiated. An extra check (<TT>nonvar(N)</TT>) is needed to distinguish the two cases.
Alternatively, we could have created two agents (delayed goals), each one
specialised for one of these cases:

	<TABLE CELLPADDING=10>
<TR><TD BGCOLOR="#CCCCFF">
	<BLOCKQUOTE CLASS="quote"><PRE>
capacity(T, N) :-
        capacity_forward(T, N),
        capacity_backward(T, N).

delay capacity_forward(T, _N) if var(T).
capacity_forward(1, N) :- N$&gt;=0.0, N$=&lt;350.0.
capacity_forward(2, N) :- N$&gt;=0.0, N$=&lt;180.0.
capacity_forward(3, N) :- N$&gt;=0.0, N$=&lt;50.0.

delay capacity_backward(_T, N) if var(N).
capacity_backward(T, N) :-
        N &gt;= 0,
        ( N =&lt; 50.0 -&gt; T :: [1,2,3]
        ; N =&lt; 180.0 -&gt; T :: [1,2]
        ; N =&lt; 350.0 -&gt; T = 1
        ; fail
        ).
</PRE></BLOCKQUOTE></TD>
</TR></TABLE>
Unfortunately, there is a drawback to this implementation as well:
once one of the two delayed goals has done its work, all the constraint's
information has been incorporated into the remaining variable's domain.
However, the other delayed goal is still waiting, and will eventually
wake up when the remaining variable gets instantiated as well, at which time
it will then do a redundant check.<BR>
<BR>
The choice between having one or several agents for a constraint is a
choice we will face every time we implement a constraint.<BR>
<BR>
<HR>
<A HREF="tutorial101.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="tutorial098.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="tutorial103.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
